home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2000 March / maximum-cd-2000-03.iso / Quake3 Game Source / Q3AGameSource.exe / Main / ui_controls2.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-18  |  51.6 KB  |  1,643 lines

  1. // Copyright (C) 1999-2000 Id Software, Inc.
  2. //
  3. /*
  4. =======================================================================
  5.  
  6. CONTROLS MENU
  7.  
  8. =======================================================================
  9. */
  10.  
  11.  
  12. #include "ui_local.h"
  13.  
  14. #define ART_BACK0            "menu/art/back_0"
  15. #define ART_BACK1            "menu/art/back_1"
  16. #define ART_FRAMEL            "menu/art/frame2_l"
  17. #define ART_FRAMER            "menu/art/frame1_r"
  18.  
  19.  
  20. typedef struct {
  21.     char    *command;
  22.     char    *label;
  23.     int        id;
  24.     int        anim;
  25.     int        defaultbind1;
  26.     int        defaultbind2;
  27.     int        bind1;
  28.     int        bind2;
  29. } bind_t;
  30.  
  31. typedef struct
  32. {
  33.     char*    name;
  34.     float    defaultvalue;
  35.     float    value;    
  36. } configcvar_t;
  37.  
  38. #define SAVE_NOOP        0
  39. #define SAVE_YES        1
  40. #define SAVE_NO            2
  41. #define SAVE_CANCEL        3
  42.  
  43. // control sections
  44. #define C_MOVEMENT        0
  45. #define C_LOOKING        1
  46. #define C_WEAPONS        2
  47. #define C_MISC            3
  48. #define C_MAX            4
  49.  
  50. #define ID_MOVEMENT        100
  51. #define ID_LOOKING        101
  52. #define ID_WEAPONS        102
  53. #define ID_MISC            103
  54. #define ID_DEFAULTS        104
  55. #define ID_BACK            105
  56. #define ID_SAVEANDEXIT    106
  57. #define ID_EXIT            107
  58.  
  59. // bindable actions
  60. #define ID_SHOWSCORES    0
  61. #define ID_USEITEM        1    
  62. #define ID_SPEED        2    
  63. #define ID_FORWARD        3    
  64. #define ID_BACKPEDAL    4
  65. #define ID_MOVELEFT        5
  66. #define ID_MOVERIGHT    6
  67. #define ID_MOVEUP        7    
  68. #define ID_MOVEDOWN        8
  69. #define ID_LEFT            9    
  70. #define ID_RIGHT        10    
  71. #define ID_STRAFE        11    
  72. #define ID_LOOKUP        12    
  73. #define ID_LOOKDOWN        13
  74. #define ID_MOUSELOOK    14
  75. #define ID_CENTERVIEW    15
  76. #define ID_ZOOMVIEW        16
  77. #define ID_WEAPON1        17    
  78. #define ID_WEAPON2        18    
  79. #define ID_WEAPON3        19    
  80. #define ID_WEAPON4        20    
  81. #define ID_WEAPON5        21    
  82. #define ID_WEAPON6        22    
  83. #define ID_WEAPON7        23    
  84. #define ID_WEAPON8        24    
  85. #define ID_WEAPON9        25    
  86. #define ID_ATTACK        26
  87. #define ID_WEAPPREV        27
  88. #define ID_WEAPNEXT        28
  89. #define ID_GESTURE        29
  90. #define ID_CHAT            30
  91. #define ID_CHAT2        31
  92. #define ID_CHAT3        32
  93. #define ID_CHAT4        33
  94.  
  95. // all others
  96. #define ID_FREELOOK        34
  97. #define ID_INVERTMOUSE    35
  98. #define ID_ALWAYSRUN    36
  99. #define ID_AUTOSWITCH    37
  100. #define ID_MOUSESPEED    38
  101. #define ID_JOYENABLE    39
  102. #define ID_JOYTHRESHOLD    40
  103. #define ID_SMOOTHMOUSE    41
  104.  
  105. #define ANIM_IDLE        0
  106. #define ANIM_RUN        1
  107. #define ANIM_WALK        2
  108. #define ANIM_BACK        3
  109. #define ANIM_JUMP        4
  110. #define ANIM_CROUCH        5
  111. #define ANIM_STEPLEFT    6
  112. #define ANIM_STEPRIGHT    7
  113. #define ANIM_TURNLEFT    8
  114. #define ANIM_TURNRIGHT    9
  115. #define ANIM_LOOKUP        10
  116. #define ANIM_LOOKDOWN    11
  117. #define ANIM_WEAPON1    12
  118. #define ANIM_WEAPON2    13
  119. #define ANIM_WEAPON3    14
  120. #define ANIM_WEAPON4    15
  121. #define ANIM_WEAPON5    16
  122. #define ANIM_WEAPON6    17
  123. #define ANIM_WEAPON7    18
  124. #define ANIM_WEAPON8    19
  125. #define ANIM_WEAPON9    20
  126. #define ANIM_WEAPON10    21
  127. #define ANIM_ATTACK        22
  128. #define ANIM_GESTURE    23
  129. #define ANIM_DIE        24
  130. #define ANIM_CHAT        25
  131.  
  132. typedef struct
  133. {
  134.     menuframework_s        menu;
  135.  
  136.     menutext_s            banner;
  137.     menubitmap_s        framel;
  138.     menubitmap_s        framer;
  139.     menubitmap_s        player;
  140.  
  141.     menutext_s            movement;
  142.     menutext_s            looking;
  143.     menutext_s            weapons;
  144.     menutext_s            misc;
  145.  
  146.     menuaction_s        walkforward;
  147.     menuaction_s        backpedal;
  148.     menuaction_s        stepleft;
  149.     menuaction_s        stepright;
  150.     menuaction_s        moveup;
  151.     menuaction_s        movedown;
  152.     menuaction_s        turnleft;
  153.     menuaction_s        turnright;
  154.     menuaction_s        sidestep;
  155.     menuaction_s        run;
  156.     menuaction_s        machinegun;
  157.     menuaction_s        chainsaw;
  158.     menuaction_s        shotgun;
  159.     menuaction_s        grenadelauncher;
  160.     menuaction_s        rocketlauncher;
  161.     menuaction_s        lightning;
  162.     menuaction_s        railgun;
  163.     menuaction_s        plasma;
  164.     menuaction_s        bfg;
  165.     menuaction_s        attack;
  166.     menuaction_s        prevweapon;
  167.     menuaction_s        nextweapon;
  168.     menuaction_s        lookup;
  169.     menuaction_s        lookdown;
  170.     menuaction_s        mouselook;
  171.     menuradiobutton_s    freelook;
  172.     menuaction_s        centerview;
  173.     menuaction_s        zoomview;
  174.     menuaction_s        gesture;
  175.     menuradiobutton_s    invertmouse;
  176.     menuslider_s        sensitivity;
  177.     menuradiobutton_s    smoothmouse;
  178.     menuradiobutton_s    alwaysrun;
  179.     menuaction_s        showscores;
  180.     menuradiobutton_s    autoswitch;
  181.     menuaction_s        useitem;
  182.     playerInfo_t        playerinfo;
  183.     qboolean            changesmade;
  184.     menuaction_s        chat;
  185.     menuaction_s        chat2;
  186.     menuaction_s        chat3;
  187.     menuaction_s        chat4;
  188.     menuradiobutton_s    joyenable;
  189.     menuslider_s        joythreshold;
  190.     int                    section;
  191.     qboolean            waitingforkey;
  192.     char                playerModel[64];
  193.     vec3_t                playerViewangles;
  194.     vec3_t                playerMoveangles;
  195.     int                    playerLegs;
  196.     int                    playerTorso;
  197.     int                    playerWeapon;
  198.     qboolean            playerChat;
  199.  
  200.     menubitmap_s        back;
  201.     menutext_s            name;
  202. } controls_t;     
  203.  
  204. static controls_t s_controls;
  205.  
  206. static vec4_t controls_binding_color  = {1.00, 0.43, 0.00, 1.00};
  207.  
  208. static bind_t g_bindings[] = 
  209. {
  210.     {"+scores",            "show scores",        ID_SHOWSCORES,    ANIM_IDLE,        K_TAB,            -1,        -1, -1},
  211.     {"+button2",        "use item",            ID_USEITEM,        ANIM_IDLE,        K_ENTER,        -1,        -1, -1},
  212.     {"+speed",             "run / walk",        ID_SPEED,        ANIM_RUN,        K_SHIFT,        -1,        -1,    -1},
  213.     {"+forward",         "walk forward",        ID_FORWARD,        ANIM_WALK,        K_UPARROW,        -1,        -1, -1},
  214.     {"+back",             "backpedal",        ID_BACKPEDAL,    ANIM_BACK,        K_DOWNARROW,    -1,        -1, -1},
  215.     {"+moveleft",         "step left",        ID_MOVELEFT,    ANIM_STEPLEFT,    ',',            -1,        -1, -1},
  216.     {"+moveright",         "step right",        ID_MOVERIGHT,    ANIM_STEPRIGHT,    '.',            -1,        -1, -1},
  217.     {"+moveup",            "up / jump",        ID_MOVEUP,        ANIM_JUMP,        K_SPACE,        -1,        -1, -1},
  218.     {"+movedown",        "down / crouch",    ID_MOVEDOWN,    ANIM_CROUCH,    'c',            -1,        -1, -1},
  219.     {"+left",             "turn left",        ID_LEFT,        ANIM_TURNLEFT,    K_LEFTARROW,    -1,        -1, -1},
  220.     {"+right",             "turn right",        ID_RIGHT,        ANIM_TURNRIGHT,    K_RIGHTARROW,    -1,        -1, -1},
  221.     {"+strafe",         "sidestep / turn",    ID_STRAFE,        ANIM_IDLE,        K_ALT,            -1,        -1, -1},
  222.     {"+lookup",         "look up",            ID_LOOKUP,        ANIM_LOOKUP,    K_PGDN,            -1,        -1, -1},
  223.     {"+lookdown",         "look down",        ID_LOOKDOWN,    ANIM_LOOKDOWN,    K_DEL,            -1,        -1, -1},
  224.     {"+mlook",             "mouse look",        ID_MOUSELOOK,    ANIM_IDLE,        '/',            -1,        -1, -1},
  225.     {"centerview",         "center view",        ID_CENTERVIEW,    ANIM_IDLE,        K_END,            -1,        -1, -1},
  226.     {"+zoom",             "zoom view",        ID_ZOOMVIEW,    ANIM_IDLE,        -1,                -1,        -1, -1},
  227.     {"weapon 1",        "gauntlet",            ID_WEAPON1,        ANIM_WEAPON1,    '1',            -1,        -1, -1},
  228.     {"weapon 2",        "machinegun",        ID_WEAPON2,        ANIM_WEAPON2,    '2',            -1,        -1, -1},
  229.     {"weapon 3",        "shotgun",            ID_WEAPON3,        ANIM_WEAPON3,    '3',            -1,        -1, -1},
  230.     {"weapon 4",        "grenade launcher",    ID_WEAPON4,        ANIM_WEAPON4,    '4',            -1,        -1, -1},
  231.     {"weapon 5",        "rocket launcher",    ID_WEAPON5,        ANIM_WEAPON5,    '5',            -1,        -1, -1},
  232.     {"weapon 6",        "lightning",        ID_WEAPON6,        ANIM_WEAPON6,    '6',            -1,        -1, -1},
  233.     {"weapon 7",        "railgun",            ID_WEAPON7,        ANIM_WEAPON7,    '7',            -1,        -1, -1},
  234.     {"weapon 8",        "plasma gun",        ID_WEAPON8,        ANIM_WEAPON8,    '8',            -1,        -1, -1},
  235.     {"weapon 9",        "BFG",                ID_WEAPON9,        ANIM_WEAPON9,    '9',            -1,        -1, -1},
  236.     {"+attack",         "attack",            ID_ATTACK,        ANIM_ATTACK,    K_CTRL,            -1,        -1, -1},
  237.     {"weapprev",        "prev weapon",        ID_WEAPPREV,    ANIM_IDLE,        '[',            -1,        -1, -1},
  238.     {"weapnext",         "next weapon",        ID_WEAPNEXT,    ANIM_IDLE,        ']',            -1,        -1, -1},
  239.     {"+button3",         "gesture",            ID_GESTURE,        ANIM_GESTURE,    K_MOUSE3,        -1,        -1, -1},
  240.     {"messagemode",     "chat",                ID_CHAT,        ANIM_CHAT,        't',            -1,        -1, -1},
  241.     {"messagemode2",     "chat - team",        ID_CHAT2,        ANIM_CHAT,        -1,                -1,        -1, -1},
  242.     {"messagemode3",     "chat - target",    ID_CHAT3,        ANIM_CHAT,        -1,                -1,        -1, -1},
  243.     {"messagemode4",     "chat - attacker",    ID_CHAT4,        ANIM_CHAT,        -1,                -1,        -1, -1},
  244.     {(char*)NULL,        (char*)NULL,        0,                0,                -1,                -1,        -1,    -1},
  245. };
  246.  
  247. static configcvar_t g_configcvars[] =
  248. {
  249.     {"cl_run",            0,                    0},
  250.     {"m_pitch",            0,                    0},
  251.     {"cg_autoswitch",    0,                    0},
  252.     {"sensitivity",        0,                    0},
  253.     {"in_joystick",        0,                    0},
  254.     {"joy_threshold",    0,                    0},
  255.     {"m_filter",        0,                    0},
  256.     {"cl_freelook",        0,                    0},
  257.     {NULL,                0,                    0}
  258. };
  259.  
  260. static menucommon_s *g_movement_controls[] =
  261. {
  262.     (menucommon_s *)&s_controls.alwaysrun,     
  263.     (menucommon_s *)&s_controls.run,            
  264.     (menucommon_s *)&s_controls.walkforward,
  265.     (menucommon_s *)&s_controls.backpedal,
  266.     (menucommon_s *)&s_controls.stepleft,      
  267.     (menucommon_s *)&s_controls.stepright,     
  268.     (menucommon_s *)&s_controls.moveup,        
  269.     (menucommon_s *)&s_controls.movedown,      
  270.     (menucommon_s *)&s_controls.turnleft,      
  271.     (menucommon_s *)&s_controls.turnright,     
  272.     (menucommon_s *)&s_controls.sidestep,
  273.     NULL
  274. };
  275.  
  276. static menucommon_s *g_weapons_controls[] = {
  277.     (menucommon_s *)&s_controls.attack,           
  278.     (menucommon_s *)&s_controls.nextweapon,
  279.     (menucommon_s *)&s_controls.prevweapon,
  280.     (menucommon_s *)&s_controls.autoswitch,    
  281.     (menucommon_s *)&s_controls.chainsaw,         
  282.     (menucommon_s *)&s_controls.machinegun,
  283.     (menucommon_s *)&s_controls.shotgun,          
  284.     (menucommon_s *)&s_controls.grenadelauncher,
  285.     (menucommon_s *)&s_controls.rocketlauncher,   
  286.     (menucommon_s *)&s_controls.lightning,   
  287.     (menucommon_s *)&s_controls.railgun,          
  288.     (menucommon_s *)&s_controls.plasma,           
  289.     (menucommon_s *)&s_controls.bfg,              
  290.     NULL,
  291. };
  292.  
  293. static menucommon_s *g_looking_controls[] = {
  294.     (menucommon_s *)&s_controls.sensitivity,
  295.     (menucommon_s *)&s_controls.smoothmouse,
  296.     (menucommon_s *)&s_controls.invertmouse,
  297.     (menucommon_s *)&s_controls.lookup,
  298.     (menucommon_s *)&s_controls.lookdown,
  299.     (menucommon_s *)&s_controls.mouselook,
  300.     (menucommon_s *)&s_controls.freelook,
  301.     (menucommon_s *)&s_controls.centerview,
  302.     (menucommon_s *)&s_controls.zoomview,
  303.     (menucommon_s *)&s_controls.joyenable,
  304.     (menucommon_s *)&s_controls.joythreshold,
  305.     NULL,
  306. };
  307.  
  308. static menucommon_s *g_misc_controls[] = {
  309.     (menucommon_s *)&s_controls.showscores, 
  310.     (menucommon_s *)&s_controls.useitem,
  311.     (menucommon_s *)&s_controls.gesture,
  312.     (menucommon_s *)&s_controls.chat,
  313.     (menucommon_s *)&s_controls.chat2,
  314.     (menucommon_s *)&s_controls.chat3,
  315.     (menucommon_s *)&s_controls.chat4,
  316.     NULL,
  317. };
  318.  
  319. static menucommon_s **g_controls[] = {
  320.     g_movement_controls,
  321.     g_looking_controls,
  322.     g_weapons_controls,
  323.     g_misc_controls,
  324. };
  325.  
  326. /*
  327. =================
  328. Controls_InitCvars
  329. =================
  330. */
  331. static void Controls_InitCvars( void )
  332. {
  333.     int                i;
  334.     configcvar_t*    cvarptr;
  335.  
  336.     cvarptr = g_configcvars;
  337.     for (i=0; ;i++,cvarptr++)
  338.     {
  339.         if (!cvarptr->name)
  340.             break;
  341.  
  342.         // get current value
  343.         cvarptr->value = trap_Cvar_VariableValue( cvarptr->name );
  344.  
  345.         // get default value
  346.         trap_Cvar_Reset( cvarptr->name );
  347.         cvarptr->defaultvalue = trap_Cvar_VariableValue( cvarptr->name );
  348.  
  349.         // restore current value
  350.         trap_Cvar_SetValue( cvarptr->name, cvarptr->value );
  351.     }
  352. }
  353.  
  354. /*
  355. =================
  356. Controls_GetCvarDefault
  357. =================
  358. */
  359. static float Controls_GetCvarDefault( char* name )
  360. {
  361.     configcvar_t*    cvarptr;
  362.     int                i;
  363.  
  364.     cvarptr = g_configcvars;
  365.     for (i=0; ;i++,cvarptr++)
  366.     {
  367.         if (!cvarptr->name)
  368.             return (0);
  369.  
  370.         if (!strcmp(cvarptr->name,name))
  371.             break;
  372.     }
  373.  
  374.     return (cvarptr->defaultvalue);
  375. }
  376.  
  377. /*
  378. =================
  379. Controls_GetCvarValue
  380. =================
  381. */
  382. static float Controls_GetCvarValue( char* name )
  383. {
  384.     configcvar_t*    cvarptr;
  385.     int                i;
  386.  
  387.     cvarptr = g_configcvars;
  388.     for (i=0; ;i++,cvarptr++)
  389.     {
  390.         if (!cvarptr->name)
  391.             return (0);
  392.  
  393.         if (!strcmp(cvarptr->name,name))
  394.             break;
  395.     }
  396.  
  397.     return (cvarptr->value);
  398. }
  399.  
  400.  
  401. /*
  402. =================
  403. Controls_UpdateModel
  404. =================
  405. */
  406. static void Controls_UpdateModel( int anim ) {
  407.     VectorClear( s_controls.playerViewangles );
  408.     VectorClear( s_controls.playerMoveangles );
  409.     s_controls.playerViewangles[YAW] = 180 - 30;
  410.     s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW];
  411.     s_controls.playerLegs             = LEGS_IDLE;
  412.     s_controls.playerTorso             = TORSO_STAND;
  413.     s_controls.playerWeapon             = -1;
  414.     s_controls.playerChat             = qfalse;
  415.  
  416.     switch( anim ) {
  417.     case ANIM_RUN:    
  418.         s_controls.playerLegs = LEGS_RUN;
  419.         break;
  420.  
  421.     case ANIM_WALK:    
  422.         s_controls.playerLegs = LEGS_WALK;
  423.         break;
  424.  
  425.     case ANIM_BACK:    
  426.         s_controls.playerLegs = LEGS_BACK;
  427.         break;
  428.  
  429.     case ANIM_JUMP:    
  430.         s_controls.playerLegs = LEGS_JUMP;
  431.         break;
  432.  
  433.     case ANIM_CROUCH:    
  434.         s_controls.playerLegs = LEGS_IDLECR;
  435.         break;
  436.  
  437.     case ANIM_TURNLEFT:
  438.         s_controls.playerViewangles[YAW] += 90;
  439.         break;
  440.  
  441.     case ANIM_TURNRIGHT:
  442.         s_controls.playerViewangles[YAW] -= 90;
  443.         break;
  444.  
  445.     case ANIM_STEPLEFT:
  446.         s_controls.playerLegs = LEGS_WALK;
  447.         s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] + 90;
  448.         break;
  449.  
  450.     case ANIM_STEPRIGHT:
  451.         s_controls.playerLegs = LEGS_WALK;
  452.         s_controls.playerMoveangles[YAW] = s_controls.playerViewangles[YAW] - 90;
  453.         break;
  454.  
  455.     case ANIM_LOOKUP:
  456.         s_controls.playerViewangles[PITCH] = -45;
  457.         break;
  458.  
  459.     case ANIM_LOOKDOWN:
  460.         s_controls.playerViewangles[PITCH] = 45;
  461.         break;
  462.  
  463.     case ANIM_WEAPON1:
  464.         s_controls.playerWeapon = WP_GAUNTLET;
  465.         break;
  466.  
  467.     case ANIM_WEAPON2:
  468.         s_controls.playerWeapon = WP_MACHINEGUN;
  469.         break;
  470.  
  471.     case ANIM_WEAPON3:
  472.         s_controls.playerWeapon = WP_SHOTGUN;
  473.         break;
  474.  
  475.     case ANIM_WEAPON4:
  476.         s_controls.playerWeapon = WP_GRENADE_LAUNCHER;
  477.         break;
  478.  
  479.     case ANIM_WEAPON5:
  480.         s_controls.playerWeapon = WP_ROCKET_LAUNCHER;
  481.         break;
  482.  
  483.     case ANIM_WEAPON6:
  484.         s_controls.playerWeapon = WP_LIGHTNING;
  485.         break;
  486.  
  487.     case ANIM_WEAPON7:
  488.         s_controls.playerWeapon = WP_RAILGUN;
  489.         break;
  490.  
  491.     case ANIM_WEAPON8:
  492.         s_controls.playerWeapon = WP_PLASMAGUN;
  493.         break;
  494.  
  495.     case ANIM_WEAPON9:
  496.         s_controls.playerWeapon = WP_BFG;
  497.         break;
  498.  
  499.     case ANIM_WEAPON10:
  500.         s_controls.playerWeapon = WP_GRAPPLING_HOOK;
  501.         break;
  502.  
  503.     case ANIM_ATTACK:
  504.         s_controls.playerTorso = TORSO_ATTACK;
  505.         break;
  506.  
  507.     case ANIM_GESTURE:
  508.         s_controls.playerTorso = TORSO_GESTURE;
  509.         break;
  510.  
  511.     case ANIM_DIE:
  512.         s_controls.playerLegs = BOTH_DEATH1;
  513.         s_controls.playerTorso = BOTH_DEATH1;
  514.         s_controls.playerWeapon = WP_NONE;
  515.         break;
  516.  
  517.     case ANIM_CHAT:
  518.         s_controls.playerChat = qtrue;
  519.         break;
  520.  
  521.     default:
  522.         break;
  523.     }
  524.  
  525.     UI_PlayerInfo_SetInfo( &s_controls.playerinfo, s_controls.playerLegs, s_controls.playerTorso, s_controls.playerViewangles, s_controls.playerMoveangles, s_controls.playerWeapon, s_controls.playerChat );
  526. }
  527.  
  528.  
  529. /*
  530. =================
  531. Controls_Update
  532. =================
  533. */
  534. static void Controls_Update( void ) {
  535.     int        i;
  536.     int        j;
  537.     int        y;
  538.     menucommon_s    **controls;
  539.     menucommon_s    *control;
  540.  
  541.     // disable all controls in all groups
  542.     for( i = 0; i < C_MAX; i++ ) {
  543.         controls = g_controls[i];
  544.         for( j = 0;    control = controls[j]; j++ ) {
  545.             control->flags |= (QMF_HIDDEN|QMF_INACTIVE);
  546.         }
  547.     }
  548.  
  549.     controls = g_controls[s_controls.section];
  550.  
  551.     // enable controls in active group (and count number of items for vertical centering)
  552.     for( j = 0;    control = controls[j]; j++ ) {
  553.         control->flags &= ~(QMF_GRAYED|QMF_HIDDEN|QMF_INACTIVE);
  554.     }
  555.  
  556.     // position controls
  557.     y = ( SCREEN_HEIGHT - j * SMALLCHAR_HEIGHT ) / 2;
  558.     for( j = 0;    control = controls[j]; j++, y += SMALLCHAR_HEIGHT ) {
  559.         control->x      = 320;
  560.         control->y      = y;
  561.         control->left   = 320 - 19*SMALLCHAR_WIDTH;
  562.         control->right  = 320 + 21*SMALLCHAR_WIDTH;
  563.         control->top    = y;
  564.         control->bottom = y + SMALLCHAR_HEIGHT;
  565.     }
  566.  
  567.     if( s_controls.waitingforkey ) {
  568.         // disable everybody
  569.         for( i = 0; i < s_controls.menu.nitems; i++ ) {
  570.             ((menucommon_s*)(s_controls.menu.items[i]))->flags |= QMF_GRAYED;
  571.         }
  572.  
  573.         // enable action item
  574.         ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->flags &= ~QMF_GRAYED;
  575.  
  576.         // don't gray out player's name
  577.         s_controls.name.generic.flags &= ~QMF_GRAYED;
  578.  
  579.         return;
  580.     }
  581.  
  582.     // enable everybody
  583.     for( i = 0; i < s_controls.menu.nitems; i++ ) {
  584.         ((menucommon_s*)(s_controls.menu.items[i]))->flags &= ~QMF_GRAYED;
  585.     }
  586.  
  587.     // makes sure flags are right on the group selection controls
  588.     s_controls.looking.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  589.     s_controls.movement.generic.flags &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  590.     s_controls.weapons.generic.flags  &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  591.     s_controls.misc.generic.flags     &= ~(QMF_GRAYED|QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  592.  
  593.     s_controls.looking.generic.flags  |= QMF_PULSEIFFOCUS;
  594.     s_controls.movement.generic.flags |= QMF_PULSEIFFOCUS;
  595.     s_controls.weapons.generic.flags  |= QMF_PULSEIFFOCUS;
  596.     s_controls.misc.generic.flags     |= QMF_PULSEIFFOCUS;
  597.  
  598.     // set buttons
  599.     switch( s_controls.section ) {
  600.     case C_MOVEMENT:
  601.         s_controls.movement.generic.flags &= ~QMF_PULSEIFFOCUS;
  602.         s_controls.movement.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  603.         break;
  604.     
  605.     case C_LOOKING:
  606.         s_controls.looking.generic.flags &= ~QMF_PULSEIFFOCUS;
  607.         s_controls.looking.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  608.         break;
  609.     
  610.     case C_WEAPONS:
  611.         s_controls.weapons.generic.flags &= ~QMF_PULSEIFFOCUS;
  612.         s_controls.weapons.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  613.         break;        
  614.  
  615.     case C_MISC:
  616.         s_controls.misc.generic.flags &= ~QMF_PULSEIFFOCUS;
  617.         s_controls.misc.generic.flags |= (QMF_HIGHLIGHT|QMF_HIGHLIGHT_IF_FOCUS);
  618.         break;
  619.     }
  620. }
  621.  
  622.  
  623. /*
  624. =================
  625. Controls_DrawKeyBinding
  626. =================
  627. */
  628. static void Controls_DrawKeyBinding( void *self )
  629. {
  630.     menuaction_s*    a;
  631.     int                x;
  632.     int                y;
  633.     int                b1;
  634.     int                b2;
  635.     qboolean        c;
  636.     char            name[32];
  637.     char            name2[32];
  638.  
  639.     a = (menuaction_s*) self;
  640.  
  641.     x =    a->generic.x;
  642.     y = a->generic.y;
  643.  
  644.     c = (Menu_ItemAtCursor( a->generic.parent ) == a);
  645.  
  646.     b1 = g_bindings[a->generic.id].bind1;
  647.     if (b1 == -1)
  648.         strcpy(name,"???");
  649.     else
  650.     {
  651.         trap_Key_KeynumToStringBuf( b1, name, 32 );
  652.         Q_strupr(name);
  653.  
  654.         b2 = g_bindings[a->generic.id].bind2;
  655.         if (b2 != -1)
  656.         {
  657.             trap_Key_KeynumToStringBuf( b2, name2, 32 );
  658.             Q_strupr(name2);
  659.  
  660.             strcat( name, " or " );
  661.             strcat( name, name2 );
  662.         }
  663.     }
  664.  
  665.     if (c)
  666.     {
  667.         UI_FillRect( a->generic.left, a->generic.top, a->generic.right-a->generic.left+1, a->generic.bottom-a->generic.top+1, listbar_color ); 
  668.  
  669.         UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_highlight );
  670.         UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT|UI_PULSE, text_color_highlight );
  671.  
  672.         if (s_controls.waitingforkey)
  673.         {
  674.             UI_DrawChar( x, y, '=', UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
  675.             UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Waiting for new key ... ESCAPE to cancel", UI_SMALLFONT|UI_CENTER|UI_PULSE, colorWhite );
  676.         }
  677.         else
  678.         {
  679.             UI_DrawChar( x, y, 13, UI_CENTER|UI_BLINK|UI_SMALLFONT, text_color_highlight);
  680.             UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.78, "Press ENTER or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
  681.             UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.82, "Press BACKSPACE to clear", UI_SMALLFONT|UI_CENTER, colorWhite );
  682.         }
  683.     }
  684.     else
  685.     {
  686.         if (a->generic.flags & QMF_GRAYED)
  687.         {
  688.             UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, text_color_disabled );
  689.             UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, text_color_disabled );
  690.         }
  691.         else
  692.         {
  693.             UI_DrawString( x - SMALLCHAR_WIDTH, y, g_bindings[a->generic.id].label, UI_RIGHT|UI_SMALLFONT, controls_binding_color );
  694.             UI_DrawString( x + SMALLCHAR_WIDTH, y, name, UI_LEFT|UI_SMALLFONT, controls_binding_color );
  695.         }
  696.     }
  697. }
  698.  
  699. /*
  700. =================
  701. Controls_StatusBar
  702. =================
  703. */
  704. static void Controls_StatusBar( void *self )
  705. {
  706.     UI_DrawString(SCREEN_WIDTH * 0.50, SCREEN_HEIGHT * 0.80, "Use Arrow Keys or CLICK to change", UI_SMALLFONT|UI_CENTER, colorWhite );
  707. }
  708.  
  709.  
  710. /*
  711. =================
  712. Controls_DrawPlayer
  713. =================
  714. */
  715. static void Controls_DrawPlayer( void *self ) {
  716.     menubitmap_s    *b;
  717.     char            buf[MAX_QPATH];
  718.  
  719.     trap_Cvar_VariableStringBuffer( "model", buf, sizeof( buf ) );
  720.     if ( strcmp( buf, s_controls.playerModel ) != 0 ) {
  721.         UI_PlayerInfo_SetModel( &s_controls.playerinfo, buf );
  722.         strcpy( s_controls.playerModel, buf );
  723.         Controls_UpdateModel( ANIM_IDLE );
  724.     }
  725.  
  726.     b = (menubitmap_s*) self;
  727.     UI_DrawPlayer( b->generic.x, b->generic.y, b->width, b->height, &s_controls.playerinfo, uis.realtime/2 );
  728. }
  729.  
  730.  
  731. /*
  732. =================
  733. Controls_GetKeyAssignment
  734. =================
  735. */
  736. static void Controls_GetKeyAssignment (char *command, int *twokeys)
  737. {
  738.     int        count;
  739.     int        j;
  740.     char    b[256];
  741.  
  742.     twokeys[0] = twokeys[1] = -1;
  743.     count = 0;
  744.  
  745.     for ( j = 0; j < 256; j++ )
  746.     {
  747.         trap_Key_GetBindingBuf( j, b, 256 );
  748.         if ( *b == 0 ) {
  749.             continue;
  750.         }
  751.         if ( !Q_stricmp( b, command ) ) {
  752.             twokeys[count] = j;
  753.             count++;
  754.             if (count == 2)
  755.                 break;
  756.         }
  757.     }
  758. }
  759.  
  760. /*
  761. =================
  762. Controls_GetConfig
  763. =================
  764. */
  765. static void Controls_GetConfig( void )
  766. {
  767.     int        i;
  768.     int        twokeys[2];
  769.     bind_t*    bindptr;
  770.  
  771.     // put the bindings into a local store
  772.     bindptr = g_bindings;
  773.  
  774.     // iterate each command, get its numeric binding
  775.     for (i=0; ;i++,bindptr++)
  776.     {
  777.         if (!bindptr->label)
  778.             break;
  779.  
  780.         Controls_GetKeyAssignment(bindptr->command, twokeys);
  781.  
  782.         bindptr->bind1 = twokeys[0];
  783.         bindptr->bind2 = twokeys[1];
  784.     }
  785.  
  786.     s_controls.invertmouse.curvalue  = Controls_GetCvarValue( "m_pitch" ) < 0;
  787.     s_controls.smoothmouse.curvalue  = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "m_filter" ) );
  788.     s_controls.alwaysrun.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_run" ) );
  789.     s_controls.autoswitch.curvalue   = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cg_autoswitch" ) );
  790.     s_controls.sensitivity.curvalue  = UI_ClampCvar( 2, 30, Controls_GetCvarValue( "sensitivity" ) );
  791.     s_controls.joyenable.curvalue    = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "in_joystick" ) );
  792.     s_controls.joythreshold.curvalue = UI_ClampCvar( 0.05, 0.75, Controls_GetCvarValue( "joy_threshold" ) );
  793.     s_controls.freelook.curvalue     = UI_ClampCvar( 0, 1, Controls_GetCvarValue( "cl_freelook" ) );
  794. }
  795.  
  796. /*
  797. =================
  798. Controls_SetConfig
  799. =================
  800. */
  801. static void Controls_SetConfig( void )
  802. {
  803.     int        i;
  804.     bind_t*    bindptr;
  805.  
  806.     // set the bindings from the local store
  807.     bindptr = g_bindings;
  808.  
  809.     // iterate each command, get its numeric binding
  810.     for (i=0; ;i++,bindptr++)
  811.     {
  812.         if (!bindptr->label)
  813.             break;
  814.  
  815.         if (bindptr->bind1 != -1)
  816.         {    
  817.             trap_Key_SetBinding( bindptr->bind1, bindptr->command );
  818.  
  819.             if (bindptr->bind2 != -1)
  820.                 trap_Key_SetBinding( bindptr->bind2, bindptr->command );
  821.         }
  822.     }
  823.  
  824.     if ( s_controls.invertmouse.curvalue )
  825.         trap_Cvar_SetValue( "m_pitch", -fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
  826.     else
  827.         trap_Cvar_SetValue( "m_pitch", fabs( trap_Cvar_VariableValue( "m_pitch" ) ) );
  828.  
  829.     trap_Cvar_SetValue( "m_filter", s_controls.smoothmouse.curvalue );
  830.     trap_Cvar_SetValue( "cl_run", s_controls.alwaysrun.curvalue );
  831.     trap_Cvar_SetValue( "cg_autoswitch", s_controls.autoswitch.curvalue );
  832.     trap_Cvar_SetValue( "sensitivity", s_controls.sensitivity.curvalue );
  833.     trap_Cvar_SetValue( "in_joystick", s_controls.joyenable.curvalue );
  834.     trap_Cvar_SetValue( "joy_threshold", s_controls.joythreshold.curvalue );
  835.     trap_Cvar_SetValue( "cl_freelook", s_controls.freelook.curvalue );
  836.     trap_Cmd_ExecuteText( EXEC_APPEND, "in_restart\n" );
  837. }
  838.  
  839. /*
  840. =================
  841. Controls_SetDefaults
  842. =================
  843. */
  844. static void Controls_SetDefaults( void )
  845. {
  846.     int    i;
  847.     bind_t*    bindptr;
  848.  
  849.     // set the bindings from the local store
  850.     bindptr = g_bindings;
  851.  
  852.     // iterate each command, set its default binding
  853.     for (i=0; ;i++,bindptr++)
  854.     {
  855.         if (!bindptr->label)
  856.             break;
  857.  
  858.         bindptr->bind1 = bindptr->defaultbind1;
  859.         bindptr->bind2 = bindptr->defaultbind2;
  860.     }
  861.  
  862.     s_controls.invertmouse.curvalue  = Controls_GetCvarDefault( "m_pitch" ) < 0;
  863.     s_controls.smoothmouse.curvalue  = Controls_GetCvarDefault( "m_filter" );
  864.     s_controls.alwaysrun.curvalue    = Controls_GetCvarDefault( "cl_run" );
  865.     s_controls.autoswitch.curvalue   = Controls_GetCvarDefault( "cg_autoswitch" );
  866.     s_controls.sensitivity.curvalue  = Controls_GetCvarDefault( "sensitivity" );
  867.     s_controls.joyenable.curvalue    = Controls_GetCvarDefault( "in_joystick" );
  868.     s_controls.joythreshold.curvalue = Controls_GetCvarDefault( "joy_threshold" );
  869.     s_controls.freelook.curvalue     = Controls_GetCvarDefault( "cl_freelook" );
  870. }
  871.  
  872. /*
  873. =================
  874. Controls_MenuKey
  875. =================
  876. */
  877. static sfxHandle_t Controls_MenuKey( int key )
  878. {
  879.     int            id;
  880.     int            i;
  881.     qboolean    found;
  882.     bind_t*        bindptr;
  883.     found = qfalse;
  884.  
  885.     if (!s_controls.waitingforkey)
  886.     {
  887.         switch (key)
  888.         {
  889.             case K_BACKSPACE:
  890.             case K_DEL:
  891.             case K_KP_DEL:
  892.                 key = -1;
  893.                 break;
  894.         
  895.             case K_MOUSE2:
  896.             case K_ESCAPE:
  897.                 if (s_controls.changesmade)
  898.                     Controls_SetConfig();
  899.                 goto ignorekey;    
  900.  
  901.             default:
  902.                 goto ignorekey;
  903.         }
  904.     }
  905.     else
  906.     {
  907.         if (key & K_CHAR_FLAG)
  908.             goto ignorekey;
  909.  
  910.         switch (key)
  911.         {
  912.             case K_ESCAPE:
  913.                 s_controls.waitingforkey = qfalse;
  914.                 Controls_Update();
  915.                 return (menu_out_sound);
  916.     
  917.             case '`':
  918.                 goto ignorekey;
  919.         }
  920.     }
  921.  
  922.     s_controls.changesmade = qtrue;
  923.     
  924.     if (key != -1)
  925.     {
  926.         // remove from any other bind
  927.         bindptr = g_bindings;
  928.         for (i=0; ;i++,bindptr++)
  929.         {
  930.             if (!bindptr->label)    
  931.                 break;
  932.  
  933.             if (bindptr->bind2 == key)
  934.                 bindptr->bind2 = -1;
  935.  
  936.             if (bindptr->bind1 == key)
  937.             {
  938.                 bindptr->bind1 = bindptr->bind2;    
  939.                 bindptr->bind2 = -1;
  940.             }
  941.         }
  942.     }
  943.  
  944.     // assign key to local store
  945.     id      = ((menucommon_s*)(s_controls.menu.items[s_controls.menu.cursor]))->id;
  946.     bindptr = g_bindings;
  947.     for (i=0; ;i++,bindptr++)
  948.     {
  949.         if (!bindptr->label)    
  950.             break;
  951.         
  952.         if (bindptr->id == id)
  953.         {
  954.             found = qtrue;
  955.             if (key == -1)
  956.             {
  957.                 if( bindptr->bind1 != -1 ) {
  958.                     trap_Key_SetBinding( bindptr->bind1, "" );
  959.                     bindptr->bind1 = -1;
  960.                 }
  961.                 if( bindptr->bind2 != -1 ) {
  962.                     trap_Key_SetBinding( bindptr->bind2, "" );
  963.                     bindptr->bind2 = -1;
  964.                 }
  965.             }
  966.             else if (bindptr->bind1 == -1) {
  967.                 bindptr->bind1 = key;
  968.             }
  969.             else if (bindptr->bind1 != key && bindptr->bind2 == -1) {
  970.                 bindptr->bind2 = key;
  971.             }
  972.             else
  973.             {
  974.                 bindptr->bind1 = key;
  975.                 bindptr->bind2 = -1;
  976.             }                        
  977.             break;
  978.         }
  979.     }                
  980.         
  981.     s_controls.waitingforkey = qfalse;
  982.  
  983.     if (found)
  984.     {    
  985.         Controls_Update();
  986.         return (menu_out_sound);
  987.     }
  988.  
  989. ignorekey:
  990.     return Menu_DefaultKey( &s_controls.menu, key );
  991. }
  992.  
  993. /*
  994. =================
  995. Controls_ResetDefaults_Action
  996. =================
  997. */
  998. static void Controls_ResetDefaults_Action( qboolean result ) {
  999.     if( !result ) {
  1000.         return;
  1001.     }
  1002.  
  1003.     s_controls.changesmade = qtrue;
  1004.     Controls_SetDefaults();
  1005.     Controls_Update();
  1006. }
  1007.  
  1008. /*
  1009. =================
  1010. Controls_ResetDefaults_Draw
  1011. =================
  1012. */
  1013. static void Controls_ResetDefaults_Draw( void ) {
  1014.     UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 0, "WARNING: This will reset all", UI_CENTER|UI_SMALLFONT, color_yellow );
  1015.     UI_DrawProportionalString( SCREEN_WIDTH/2, 356 + PROP_HEIGHT * 1, "controls to their default values.", UI_CENTER|UI_SMALLFONT, color_yellow );
  1016. }
  1017.  
  1018. /*
  1019. =================
  1020. Controls_MenuEvent
  1021. =================
  1022. */
  1023. static void Controls_MenuEvent( void* ptr, int event )
  1024. {
  1025.     switch (((menucommon_s*)ptr)->id)
  1026.     {
  1027.         case ID_MOVEMENT:
  1028.             if (event == QM_ACTIVATED)
  1029.             {
  1030.                 s_controls.section = C_MOVEMENT; 
  1031.                 Controls_Update();
  1032.             }
  1033.             break;
  1034.  
  1035.         case ID_LOOKING:
  1036.             if (event == QM_ACTIVATED)
  1037.             {
  1038.                 s_controls.section = C_LOOKING; 
  1039.                 Controls_Update();
  1040.             }
  1041.             break;
  1042.  
  1043.         case ID_WEAPONS:
  1044.             if (event == QM_ACTIVATED)
  1045.             {
  1046.                 s_controls.section = C_WEAPONS; 
  1047.                 Controls_Update();
  1048.             }
  1049.             break;
  1050.  
  1051.         case ID_MISC:
  1052.             if (event == QM_ACTIVATED)
  1053.             {
  1054.                 s_controls.section = C_MISC; 
  1055.                 Controls_Update();
  1056.             }
  1057.             break;
  1058.  
  1059.         case ID_DEFAULTS:
  1060.             if (event == QM_ACTIVATED)
  1061.             {
  1062.                 UI_ConfirmMenu( "SET TO DEFAULTS?", Controls_ResetDefaults_Draw, Controls_ResetDefaults_Action );
  1063.             }
  1064.             break;
  1065.  
  1066.         case ID_BACK:
  1067.             if (event == QM_ACTIVATED)
  1068.             {
  1069.                 if (s_controls.changesmade)
  1070.                     Controls_SetConfig();
  1071.                 UI_PopMenu();
  1072.             }
  1073.             break;
  1074.  
  1075.         case ID_SAVEANDEXIT:
  1076.             if (event == QM_ACTIVATED)
  1077.             {
  1078.                 Controls_SetConfig();
  1079.                 UI_PopMenu();
  1080.             }
  1081.             break;
  1082.  
  1083.         case ID_EXIT:
  1084.             if (event == QM_ACTIVATED)
  1085.             {
  1086.                 UI_PopMenu();
  1087.             }
  1088.             break;
  1089.  
  1090.         case ID_FREELOOK:
  1091.         case ID_MOUSESPEED:
  1092.         case ID_INVERTMOUSE:
  1093.         case ID_SMOOTHMOUSE:
  1094.         case ID_ALWAYSRUN:
  1095.         case ID_AUTOSWITCH:
  1096.         case ID_JOYENABLE:
  1097.         case ID_JOYTHRESHOLD:
  1098.             if (event == QM_ACTIVATED)
  1099.             {
  1100.                 s_controls.changesmade = qtrue;
  1101.             }
  1102.             break;        
  1103.     }
  1104. }
  1105.  
  1106. /*
  1107. =================
  1108. Controls_ActionEvent
  1109. =================
  1110. */
  1111. static void Controls_ActionEvent( void* ptr, int event )
  1112. {
  1113.     if (event == QM_LOSTFOCUS)
  1114.     {
  1115.         Controls_UpdateModel( ANIM_IDLE );
  1116.     }
  1117.     else if (event == QM_GOTFOCUS)
  1118.     {
  1119.         Controls_UpdateModel( g_bindings[((menucommon_s*)ptr)->id].anim );
  1120.     }
  1121.     else if ((event == QM_ACTIVATED) && !s_controls.waitingforkey)
  1122.     {
  1123.         s_controls.waitingforkey = 1;
  1124.         Controls_Update();
  1125.     }
  1126. }
  1127.  
  1128. /*
  1129. =================
  1130. Controls_InitModel
  1131. =================
  1132. */
  1133. static void Controls_InitModel( void )
  1134. {
  1135.     memset( &s_controls.playerinfo, 0, sizeof(playerInfo_t) );
  1136.  
  1137.     UI_PlayerInfo_SetModel( &s_controls.playerinfo, UI_Cvar_VariableString( "model" ) );
  1138.  
  1139.     Controls_UpdateModel( ANIM_IDLE );
  1140. }
  1141.  
  1142. /*
  1143. =================
  1144. Controls_InitWeapons
  1145. =================
  1146. */
  1147. static void Controls_InitWeapons( void ) {
  1148.     gitem_t *    item;
  1149.  
  1150.     for ( item = bg_itemlist + 1 ; item->classname ; item++ ) {
  1151.         if ( item->giType != IT_WEAPON ) {
  1152.             continue;
  1153.         }
  1154.         trap_R_RegisterModel( item->world_model[0] );
  1155.     }
  1156. }
  1157.  
  1158. /*
  1159. =================
  1160. Controls_MenuInit
  1161. =================
  1162. */
  1163. static void Controls_MenuInit( void )
  1164. {
  1165.     static char playername[32];
  1166.  
  1167.     // zero set all our globals
  1168.     memset( &s_controls, 0 ,sizeof(controls_t) );
  1169.  
  1170.     Controls_Cache();
  1171.  
  1172.     s_controls.menu.key        = Controls_MenuKey;
  1173.     s_controls.menu.wrapAround = qtrue;
  1174.     s_controls.menu.fullscreen = qtrue;
  1175.  
  1176.     s_controls.banner.generic.type    = MTYPE_BTEXT;
  1177.     s_controls.banner.generic.flags    = QMF_CENTER_JUSTIFY;
  1178.     s_controls.banner.generic.x        = 320;
  1179.     s_controls.banner.generic.y        = 16;
  1180.     s_controls.banner.string        = "CONTROLS";
  1181.     s_controls.banner.color            = color_white;
  1182.     s_controls.banner.style            = UI_CENTER;
  1183.  
  1184.     s_controls.framel.generic.type  = MTYPE_BITMAP;
  1185.     s_controls.framel.generic.name  = ART_FRAMEL;
  1186.     s_controls.framel.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
  1187.     s_controls.framel.generic.x     = 0;
  1188.     s_controls.framel.generic.y     = 78;
  1189.     s_controls.framel.width          = 256;
  1190.     s_controls.framel.height          = 329;
  1191.  
  1192.     s_controls.framer.generic.type  = MTYPE_BITMAP;
  1193.     s_controls.framer.generic.name  = ART_FRAMER;
  1194.     s_controls.framer.generic.flags = QMF_LEFT_JUSTIFY|QMF_INACTIVE;
  1195.     s_controls.framer.generic.x     = 376;
  1196.     s_controls.framer.generic.y     = 76;
  1197.     s_controls.framer.width          = 256;
  1198.     s_controls.framer.height          = 334;
  1199.  
  1200.     s_controls.looking.generic.type     = MTYPE_PTEXT;
  1201.     s_controls.looking.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
  1202.     s_controls.looking.generic.id        = ID_LOOKING;
  1203.     s_controls.looking.generic.callback    = Controls_MenuEvent;
  1204.     s_controls.looking.generic.x        = 152;
  1205.     s_controls.looking.generic.y        = 240 - 2 * PROP_HEIGHT;
  1206.     s_controls.looking.string            = "LOOK";
  1207.     s_controls.looking.style            = UI_RIGHT;
  1208.     s_controls.looking.color            = color_red;
  1209.  
  1210.     s_controls.movement.generic.type     = MTYPE_PTEXT;
  1211.     s_controls.movement.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
  1212.     s_controls.movement.generic.id         = ID_MOVEMENT;
  1213.     s_controls.movement.generic.callback = Controls_MenuEvent;
  1214.     s_controls.movement.generic.x         = 152;
  1215.     s_controls.movement.generic.y         = 240 - PROP_HEIGHT;
  1216.     s_controls.movement.string            = "MOVE";
  1217.     s_controls.movement.style            = UI_RIGHT;
  1218.     s_controls.movement.color            = color_red;
  1219.  
  1220.     s_controls.weapons.generic.type        = MTYPE_PTEXT;
  1221.     s_controls.weapons.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
  1222.     s_controls.weapons.generic.id        = ID_WEAPONS;
  1223.     s_controls.weapons.generic.callback    = Controls_MenuEvent;
  1224.     s_controls.weapons.generic.x        = 152;
  1225.     s_controls.weapons.generic.y        = 240;
  1226.     s_controls.weapons.string            = "SHOOT";
  1227.     s_controls.weapons.style            = UI_RIGHT;
  1228.     s_controls.weapons.color            = color_red;
  1229.  
  1230.     s_controls.misc.generic.type     = MTYPE_PTEXT;
  1231.     s_controls.misc.generic.flags    = QMF_RIGHT_JUSTIFY|QMF_PULSEIFFOCUS;
  1232.     s_controls.misc.generic.id         = ID_MISC;
  1233.     s_controls.misc.generic.callback = Controls_MenuEvent;
  1234.     s_controls.misc.generic.x         = 152;
  1235.     s_controls.misc.generic.y         = 240 + PROP_HEIGHT;
  1236.     s_controls.misc.string            = "MISC";
  1237.     s_controls.misc.style            = UI_RIGHT;
  1238.     s_controls.misc.color            = color_red;
  1239.  
  1240.     s_controls.back.generic.type     = MTYPE_BITMAP;
  1241.     s_controls.back.generic.name     = ART_BACK0;
  1242.     s_controls.back.generic.flags    = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS;
  1243.     s_controls.back.generic.x         = 0;
  1244.     s_controls.back.generic.y         = 480-64;
  1245.     s_controls.back.generic.id         = ID_BACK;
  1246.     s_controls.back.generic.callback = Controls_MenuEvent;
  1247.     s_controls.back.width               = 128;
  1248.     s_controls.back.height           = 64;
  1249.     s_controls.back.focuspic         = ART_BACK1;
  1250.  
  1251.     s_controls.player.generic.type      = MTYPE_BITMAP;
  1252.     s_controls.player.generic.flags     = QMF_INACTIVE;
  1253.     s_controls.player.generic.ownerdraw = Controls_DrawPlayer;
  1254.     s_controls.player.generic.x            = 400;
  1255.     s_controls.player.generic.y            = -40;
  1256.     s_controls.player.width                = 32*10;
  1257.     s_controls.player.height            = 56*10;
  1258.  
  1259.     s_controls.walkforward.generic.type         = MTYPE_ACTION;
  1260.     s_controls.walkforward.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1261.     s_controls.walkforward.generic.callback  = Controls_ActionEvent;
  1262.     s_controls.walkforward.generic.ownerdraw = Controls_DrawKeyBinding;
  1263.     s_controls.walkforward.generic.id          = ID_FORWARD;
  1264.  
  1265.     s_controls.backpedal.generic.type       = MTYPE_ACTION;
  1266.     s_controls.backpedal.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1267.     s_controls.backpedal.generic.callback  = Controls_ActionEvent;
  1268.     s_controls.backpedal.generic.ownerdraw = Controls_DrawKeyBinding;
  1269.     s_controls.backpedal.generic.id        = ID_BACKPEDAL;
  1270.  
  1271.     s_controls.stepleft.generic.type      = MTYPE_ACTION;
  1272.     s_controls.stepleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1273.     s_controls.stepleft.generic.callback  = Controls_ActionEvent;
  1274.     s_controls.stepleft.generic.ownerdraw = Controls_DrawKeyBinding;
  1275.     s_controls.stepleft.generic.id           = ID_MOVELEFT;
  1276.  
  1277.     s_controls.stepright.generic.type       = MTYPE_ACTION;
  1278.     s_controls.stepright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1279.     s_controls.stepright.generic.callback  = Controls_ActionEvent;
  1280.     s_controls.stepright.generic.ownerdraw = Controls_DrawKeyBinding;
  1281.     s_controls.stepright.generic.id        = ID_MOVERIGHT;
  1282.  
  1283.     s_controls.moveup.generic.type        = MTYPE_ACTION;
  1284.     s_controls.moveup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1285.     s_controls.moveup.generic.callback  = Controls_ActionEvent;
  1286.     s_controls.moveup.generic.ownerdraw = Controls_DrawKeyBinding;
  1287.     s_controls.moveup.generic.id        = ID_MOVEUP;
  1288.  
  1289.     s_controls.movedown.generic.type      = MTYPE_ACTION;
  1290.     s_controls.movedown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1291.     s_controls.movedown.generic.callback  = Controls_ActionEvent;
  1292.     s_controls.movedown.generic.ownerdraw = Controls_DrawKeyBinding;
  1293.     s_controls.movedown.generic.id        = ID_MOVEDOWN;
  1294.  
  1295.     s_controls.turnleft.generic.type      = MTYPE_ACTION;
  1296.     s_controls.turnleft.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1297.     s_controls.turnleft.generic.callback  = Controls_ActionEvent;
  1298.     s_controls.turnleft.generic.ownerdraw = Controls_DrawKeyBinding;
  1299.     s_controls.turnleft.generic.id        = ID_LEFT;
  1300.  
  1301.     s_controls.turnright.generic.type       = MTYPE_ACTION;
  1302.     s_controls.turnright.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1303.     s_controls.turnright.generic.callback  = Controls_ActionEvent;
  1304.     s_controls.turnright.generic.ownerdraw = Controls_DrawKeyBinding;
  1305.     s_controls.turnright.generic.id        = ID_RIGHT;
  1306.  
  1307.     s_controls.sidestep.generic.type      = MTYPE_ACTION;
  1308.     s_controls.sidestep.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1309.     s_controls.sidestep.generic.callback  = Controls_ActionEvent;
  1310.     s_controls.sidestep.generic.ownerdraw = Controls_DrawKeyBinding;
  1311.     s_controls.sidestep.generic.id        = ID_STRAFE;
  1312.  
  1313.     s_controls.run.generic.type         = MTYPE_ACTION;
  1314.     s_controls.run.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1315.     s_controls.run.generic.callback  = Controls_ActionEvent;
  1316.     s_controls.run.generic.ownerdraw = Controls_DrawKeyBinding;
  1317.     s_controls.run.generic.id        = ID_SPEED;
  1318.  
  1319.     s_controls.chainsaw.generic.type      = MTYPE_ACTION;
  1320.     s_controls.chainsaw.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1321.     s_controls.chainsaw.generic.callback  = Controls_ActionEvent;
  1322.     s_controls.chainsaw.generic.ownerdraw = Controls_DrawKeyBinding;
  1323.     s_controls.chainsaw.generic.id        = ID_WEAPON1;
  1324.  
  1325.     s_controls.machinegun.generic.type        = MTYPE_ACTION;
  1326.     s_controls.machinegun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1327.     s_controls.machinegun.generic.callback  = Controls_ActionEvent;
  1328.     s_controls.machinegun.generic.ownerdraw = Controls_DrawKeyBinding;
  1329.     s_controls.machinegun.generic.id        = ID_WEAPON2;
  1330.  
  1331.     s_controls.shotgun.generic.type         = MTYPE_ACTION;
  1332.     s_controls.shotgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1333.     s_controls.shotgun.generic.callback  = Controls_ActionEvent;
  1334.     s_controls.shotgun.generic.ownerdraw = Controls_DrawKeyBinding;
  1335.     s_controls.shotgun.generic.id        = ID_WEAPON3;
  1336.  
  1337.     s_controls.grenadelauncher.generic.type         = MTYPE_ACTION;
  1338.     s_controls.grenadelauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1339.     s_controls.grenadelauncher.generic.callback  = Controls_ActionEvent;
  1340.     s_controls.grenadelauncher.generic.ownerdraw = Controls_DrawKeyBinding;
  1341.     s_controls.grenadelauncher.generic.id        = ID_WEAPON4;
  1342.  
  1343.     s_controls.rocketlauncher.generic.type        = MTYPE_ACTION;
  1344.     s_controls.rocketlauncher.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1345.     s_controls.rocketlauncher.generic.callback  = Controls_ActionEvent;
  1346.     s_controls.rocketlauncher.generic.ownerdraw = Controls_DrawKeyBinding;
  1347.     s_controls.rocketlauncher.generic.id        = ID_WEAPON5;
  1348.  
  1349.     s_controls.lightning.generic.type       = MTYPE_ACTION;
  1350.     s_controls.lightning.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1351.     s_controls.lightning.generic.callback  = Controls_ActionEvent;
  1352.     s_controls.lightning.generic.ownerdraw = Controls_DrawKeyBinding;
  1353.     s_controls.lightning.generic.id        = ID_WEAPON6;
  1354.  
  1355.     s_controls.railgun.generic.type         = MTYPE_ACTION;
  1356.     s_controls.railgun.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1357.     s_controls.railgun.generic.callback  = Controls_ActionEvent;
  1358.     s_controls.railgun.generic.ownerdraw = Controls_DrawKeyBinding;
  1359.     s_controls.railgun.generic.id        = ID_WEAPON7;
  1360.  
  1361.     s_controls.plasma.generic.type        = MTYPE_ACTION;
  1362.     s_controls.plasma.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1363.     s_controls.plasma.generic.callback  = Controls_ActionEvent;
  1364.     s_controls.plasma.generic.ownerdraw = Controls_DrawKeyBinding;
  1365.     s_controls.plasma.generic.id        = ID_WEAPON8;
  1366.  
  1367.     s_controls.bfg.generic.type         = MTYPE_ACTION;
  1368.     s_controls.bfg.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1369.     s_controls.bfg.generic.callback  = Controls_ActionEvent;
  1370.     s_controls.bfg.generic.ownerdraw = Controls_DrawKeyBinding;
  1371.     s_controls.bfg.generic.id        = ID_WEAPON9;
  1372.  
  1373.     s_controls.attack.generic.type        = MTYPE_ACTION;
  1374.     s_controls.attack.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1375.     s_controls.attack.generic.callback  = Controls_ActionEvent;
  1376.     s_controls.attack.generic.ownerdraw = Controls_DrawKeyBinding;
  1377.     s_controls.attack.generic.id        = ID_ATTACK;
  1378.  
  1379.     s_controls.prevweapon.generic.type        = MTYPE_ACTION;
  1380.     s_controls.prevweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1381.     s_controls.prevweapon.generic.callback  = Controls_ActionEvent;
  1382.     s_controls.prevweapon.generic.ownerdraw = Controls_DrawKeyBinding;
  1383.     s_controls.prevweapon.generic.id        = ID_WEAPPREV;
  1384.  
  1385.     s_controls.nextweapon.generic.type        = MTYPE_ACTION;
  1386.     s_controls.nextweapon.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1387.     s_controls.nextweapon.generic.callback  = Controls_ActionEvent;
  1388.     s_controls.nextweapon.generic.ownerdraw = Controls_DrawKeyBinding;
  1389.     s_controls.nextweapon.generic.id        = ID_WEAPNEXT;
  1390.  
  1391.     s_controls.lookup.generic.type        = MTYPE_ACTION;
  1392.     s_controls.lookup.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1393.     s_controls.lookup.generic.callback  = Controls_ActionEvent;
  1394.     s_controls.lookup.generic.ownerdraw = Controls_DrawKeyBinding;
  1395.     s_controls.lookup.generic.id        = ID_LOOKUP;
  1396.  
  1397.     s_controls.lookdown.generic.type      = MTYPE_ACTION;
  1398.     s_controls.lookdown.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1399.     s_controls.lookdown.generic.callback  = Controls_ActionEvent;
  1400.     s_controls.lookdown.generic.ownerdraw = Controls_DrawKeyBinding;
  1401.     s_controls.lookdown.generic.id        = ID_LOOKDOWN;
  1402.  
  1403.     s_controls.mouselook.generic.type       = MTYPE_ACTION;
  1404.     s_controls.mouselook.generic.flags     = QMF_LEFT_JUSTIFY|QMF_HIGHLIGHT_IF_FOCUS|QMF_GRAYED|QMF_HIDDEN;
  1405.     s_controls.mouselook.generic.callback  = Controls_ActionEvent;
  1406.     s_controls.mouselook.generic.ownerdraw = Controls_DrawKeyBinding;
  1407.     s_controls.mouselook.generic.id        = ID_MOUSELOOK;
  1408.  
  1409.     s_controls.freelook.generic.type        = MTYPE_RADIOBUTTON;
  1410.     s_controls.freelook.generic.flags        = QMF_SMALLFONT;
  1411.     s_controls.freelook.generic.x            = SCREEN_WIDTH/2;
  1412.     s_controls.freelook.generic.name        = "free look";
  1413.     s_controls.freelook.generic.id            = ID_FREELOOK;
  1414.     s_controls.freelook.generic.callback    = Controls_MenuEvent;
  1415.     s_controls.freelook.generic.statusbar    = Controls_StatusBar;
  1416.  
  1417.     s_controls.centerview.generic.type        = MTYPE_ACTION;
  1418.     s_controls.centerview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1419.     s_controls.centerview.generic.callback  = Controls_ActionEvent;
  1420.     s_controls.centerview.generic.ownerdraw = Controls_DrawKeyBinding;
  1421.     s_controls.centerview.generic.id        = ID_CENTERVIEW;
  1422.  
  1423.     s_controls.zoomview.generic.type      = MTYPE_ACTION;
  1424.     s_controls.zoomview.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1425.     s_controls.zoomview.generic.callback  = Controls_ActionEvent;
  1426.     s_controls.zoomview.generic.ownerdraw = Controls_DrawKeyBinding;
  1427.     s_controls.zoomview.generic.id        = ID_ZOOMVIEW;
  1428.  
  1429.     s_controls.useitem.generic.type         = MTYPE_ACTION;
  1430.     s_controls.useitem.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1431.     s_controls.useitem.generic.callback  = Controls_ActionEvent;
  1432.     s_controls.useitem.generic.ownerdraw = Controls_DrawKeyBinding;
  1433.     s_controls.useitem.generic.id        = ID_USEITEM;
  1434.  
  1435.     s_controls.showscores.generic.type        = MTYPE_ACTION;
  1436.     s_controls.showscores.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1437.     s_controls.showscores.generic.callback  = Controls_ActionEvent;
  1438.     s_controls.showscores.generic.ownerdraw = Controls_DrawKeyBinding;
  1439.     s_controls.showscores.generic.id        = ID_SHOWSCORES;
  1440.  
  1441.     s_controls.invertmouse.generic.type      = MTYPE_RADIOBUTTON;
  1442.     s_controls.invertmouse.generic.flags     = QMF_SMALLFONT;
  1443.     s_controls.invertmouse.generic.x         = SCREEN_WIDTH/2;
  1444.     s_controls.invertmouse.generic.name         = "invert mouse";
  1445.     s_controls.invertmouse.generic.id        = ID_INVERTMOUSE;
  1446.     s_controls.invertmouse.generic.callback  = Controls_MenuEvent;
  1447.     s_controls.invertmouse.generic.statusbar = Controls_StatusBar;
  1448.  
  1449.     s_controls.smoothmouse.generic.type      = MTYPE_RADIOBUTTON;
  1450.     s_controls.smoothmouse.generic.flags     = QMF_SMALLFONT;
  1451.     s_controls.smoothmouse.generic.x         = SCREEN_WIDTH/2;
  1452.     s_controls.smoothmouse.generic.name         = "smooth mouse";
  1453.     s_controls.smoothmouse.generic.id        = ID_SMOOTHMOUSE;
  1454.     s_controls.smoothmouse.generic.callback  = Controls_MenuEvent;
  1455.     s_controls.smoothmouse.generic.statusbar = Controls_StatusBar;
  1456.  
  1457.     s_controls.alwaysrun.generic.type      = MTYPE_RADIOBUTTON;
  1458.     s_controls.alwaysrun.generic.flags       = QMF_SMALLFONT;
  1459.     s_controls.alwaysrun.generic.x           = SCREEN_WIDTH/2;
  1460.     s_controls.alwaysrun.generic.name       = "always run";
  1461.     s_controls.alwaysrun.generic.id        = ID_ALWAYSRUN;
  1462.     s_controls.alwaysrun.generic.callback  = Controls_MenuEvent;
  1463.     s_controls.alwaysrun.generic.statusbar = Controls_StatusBar;
  1464.  
  1465.     s_controls.autoswitch.generic.type      = MTYPE_RADIOBUTTON;
  1466.     s_controls.autoswitch.generic.flags        = QMF_SMALLFONT;
  1467.     s_controls.autoswitch.generic.x            = SCREEN_WIDTH/2;
  1468.     s_controls.autoswitch.generic.name        = "autoswitch weapons";
  1469.     s_controls.autoswitch.generic.id        = ID_AUTOSWITCH;
  1470.     s_controls.autoswitch.generic.callback  = Controls_MenuEvent;
  1471.     s_controls.autoswitch.generic.statusbar = Controls_StatusBar;
  1472.  
  1473.     s_controls.sensitivity.generic.type         = MTYPE_SLIDER;
  1474.     s_controls.sensitivity.generic.x         = SCREEN_WIDTH/2;
  1475.     s_controls.sensitivity.generic.flags     = QMF_SMALLFONT;
  1476.     s_controls.sensitivity.generic.name         = "mouse speed";
  1477.     s_controls.sensitivity.generic.id          = ID_MOUSESPEED;
  1478.     s_controls.sensitivity.generic.callback  = Controls_MenuEvent;
  1479.     s_controls.sensitivity.minvalue             = 2;
  1480.     s_controls.sensitivity.maxvalue             = 30;
  1481.     s_controls.sensitivity.generic.statusbar = Controls_StatusBar;
  1482.  
  1483.     s_controls.gesture.generic.type         = MTYPE_ACTION;
  1484.     s_controls.gesture.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1485.     s_controls.gesture.generic.callback  = Controls_ActionEvent;
  1486.     s_controls.gesture.generic.ownerdraw = Controls_DrawKeyBinding;
  1487.     s_controls.gesture.generic.id        = ID_GESTURE;
  1488.  
  1489.     s_controls.chat.generic.type      = MTYPE_ACTION;
  1490.     s_controls.chat.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1491.     s_controls.chat.generic.callback  = Controls_ActionEvent;
  1492.     s_controls.chat.generic.ownerdraw = Controls_DrawKeyBinding;
  1493.     s_controls.chat.generic.id        = ID_CHAT;
  1494.  
  1495.     s_controls.chat2.generic.type       = MTYPE_ACTION;
  1496.     s_controls.chat2.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1497.     s_controls.chat2.generic.callback  = Controls_ActionEvent;
  1498.     s_controls.chat2.generic.ownerdraw = Controls_DrawKeyBinding;
  1499.     s_controls.chat2.generic.id        = ID_CHAT2;
  1500.  
  1501.     s_controls.chat3.generic.type       = MTYPE_ACTION;
  1502.     s_controls.chat3.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1503.     s_controls.chat3.generic.callback  = Controls_ActionEvent;
  1504.     s_controls.chat3.generic.ownerdraw = Controls_DrawKeyBinding;
  1505.     s_controls.chat3.generic.id        = ID_CHAT3;
  1506.  
  1507.     s_controls.chat4.generic.type       = MTYPE_ACTION;
  1508.     s_controls.chat4.generic.flags     = QMF_LEFT_JUSTIFY|QMF_PULSEIFFOCUS|QMF_GRAYED|QMF_HIDDEN;
  1509.     s_controls.chat4.generic.callback  = Controls_ActionEvent;
  1510.     s_controls.chat4.generic.ownerdraw = Controls_DrawKeyBinding;
  1511.     s_controls.chat4.generic.id        = ID_CHAT4;
  1512.  
  1513.     s_controls.joyenable.generic.type      = MTYPE_RADIOBUTTON;
  1514.     s_controls.joyenable.generic.flags       = QMF_SMALLFONT;
  1515.     s_controls.joyenable.generic.x           = SCREEN_WIDTH/2;
  1516.     s_controls.joyenable.generic.name       = "joystick";
  1517.     s_controls.joyenable.generic.id        = ID_JOYENABLE;
  1518.     s_controls.joyenable.generic.callback  = Controls_MenuEvent;
  1519.     s_controls.joyenable.generic.statusbar = Controls_StatusBar;
  1520.  
  1521.     s_controls.joythreshold.generic.type      = MTYPE_SLIDER;
  1522.     s_controls.joythreshold.generic.x          = SCREEN_WIDTH/2;
  1523.     s_controls.joythreshold.generic.flags      = QMF_SMALLFONT;
  1524.     s_controls.joythreshold.generic.name      = "joystick threshold";
  1525.     s_controls.joythreshold.generic.id           = ID_JOYTHRESHOLD;
  1526.     s_controls.joythreshold.generic.callback  = Controls_MenuEvent;
  1527.     s_controls.joythreshold.minvalue          = 0.05;
  1528.     s_controls.joythreshold.maxvalue          = 0.75;
  1529.     s_controls.joythreshold.generic.statusbar = Controls_StatusBar;
  1530.  
  1531.     s_controls.name.generic.type    = MTYPE_PTEXT;
  1532.     s_controls.name.generic.flags    = QMF_CENTER_JUSTIFY|QMF_INACTIVE;
  1533.     s_controls.name.generic.x        = 320;
  1534.     s_controls.name.generic.y        = 440;
  1535.     s_controls.name.string            = playername;
  1536.     s_controls.name.style            = UI_CENTER;
  1537.     s_controls.name.color            = text_color_normal;
  1538.  
  1539.     Menu_AddItem( &s_controls.menu, &s_controls.banner );
  1540.     Menu_AddItem( &s_controls.menu, &s_controls.framel );
  1541.     Menu_AddItem( &s_controls.menu, &s_controls.framer );
  1542.     Menu_AddItem( &s_controls.menu, &s_controls.player );
  1543.     Menu_AddItem( &s_controls.menu, &s_controls.name );
  1544.  
  1545.     Menu_AddItem( &s_controls.menu, &s_controls.looking );
  1546.     Menu_AddItem( &s_controls.menu, &s_controls.movement );
  1547.     Menu_AddItem( &s_controls.menu, &s_controls.weapons );
  1548.     Menu_AddItem( &s_controls.menu, &s_controls.misc );
  1549.  
  1550.     Menu_AddItem( &s_controls.menu, &s_controls.sensitivity );
  1551.     Menu_AddItem( &s_controls.menu, &s_controls.smoothmouse );
  1552.     Menu_AddItem( &s_controls.menu, &s_controls.invertmouse );
  1553.     Menu_AddItem( &s_controls.menu, &s_controls.lookup );
  1554.     Menu_AddItem( &s_controls.menu, &s_controls.lookdown );
  1555.     Menu_AddItem( &s_controls.menu, &s_controls.mouselook );
  1556.     Menu_AddItem( &s_controls.menu, &s_controls.freelook );
  1557.     Menu_AddItem( &s_controls.menu, &s_controls.centerview );
  1558.     Menu_AddItem( &s_controls.menu, &s_controls.zoomview );
  1559.     Menu_AddItem( &s_controls.menu, &s_controls.joyenable );
  1560.     Menu_AddItem( &s_controls.menu, &s_controls.joythreshold );
  1561.  
  1562.     Menu_AddItem( &s_controls.menu, &s_controls.alwaysrun );
  1563.     Menu_AddItem( &s_controls.menu, &s_controls.run );
  1564.     Menu_AddItem( &s_controls.menu, &s_controls.walkforward );
  1565.     Menu_AddItem( &s_controls.menu, &s_controls.backpedal );
  1566.     Menu_AddItem( &s_controls.menu, &s_controls.stepleft );
  1567.     Menu_AddItem( &s_controls.menu, &s_controls.stepright );
  1568.     Menu_AddItem( &s_controls.menu, &s_controls.moveup );
  1569.     Menu_AddItem( &s_controls.menu, &s_controls.movedown );
  1570.     Menu_AddItem( &s_controls.menu, &s_controls.turnleft );
  1571.     Menu_AddItem( &s_controls.menu, &s_controls.turnright );
  1572.     Menu_AddItem( &s_controls.menu, &s_controls.sidestep );
  1573.  
  1574.     Menu_AddItem( &s_controls.menu, &s_controls.attack );
  1575.     Menu_AddItem( &s_controls.menu, &s_controls.nextweapon );
  1576.     Menu_AddItem( &s_controls.menu, &s_controls.prevweapon );
  1577.     Menu_AddItem( &s_controls.menu, &s_controls.autoswitch );
  1578.     Menu_AddItem( &s_controls.menu, &s_controls.chainsaw );
  1579.     Menu_AddItem( &s_controls.menu, &s_controls.machinegun );
  1580.     Menu_AddItem( &s_controls.menu, &s_controls.shotgun );
  1581.     Menu_AddItem( &s_controls.menu, &s_controls.grenadelauncher );
  1582.     Menu_AddItem( &s_controls.menu, &s_controls.rocketlauncher );
  1583.     Menu_AddItem( &s_controls.menu, &s_controls.lightning );
  1584.     Menu_AddItem( &s_controls.menu, &s_controls.railgun );
  1585.     Menu_AddItem( &s_controls.menu, &s_controls.plasma );
  1586.     Menu_AddItem( &s_controls.menu, &s_controls.bfg );
  1587.  
  1588.     Menu_AddItem( &s_controls.menu, &s_controls.showscores );
  1589.     Menu_AddItem( &s_controls.menu, &s_controls.useitem );
  1590.     Menu_AddItem( &s_controls.menu, &s_controls.gesture );
  1591.     Menu_AddItem( &s_controls.menu, &s_controls.chat );
  1592.     Menu_AddItem( &s_controls.menu, &s_controls.chat2 );
  1593.     Menu_AddItem( &s_controls.menu, &s_controls.chat3 );
  1594.     Menu_AddItem( &s_controls.menu, &s_controls.chat4 );
  1595.  
  1596.     Menu_AddItem( &s_controls.menu, &s_controls.back );
  1597.  
  1598.     trap_Cvar_VariableStringBuffer( "name", s_controls.name.string, 16 );
  1599.     Q_CleanStr( s_controls.name.string );
  1600.  
  1601.     // initialize the configurable cvars
  1602.     Controls_InitCvars();
  1603.  
  1604.     // initialize the current config
  1605.     Controls_GetConfig();
  1606.  
  1607.     // intialize the model
  1608.     Controls_InitModel();
  1609.  
  1610.     // intialize the weapons
  1611.     Controls_InitWeapons ();
  1612.  
  1613.     // initial default section
  1614.     s_controls.section = C_LOOKING;
  1615.  
  1616.     // update the ui
  1617.     Controls_Update();
  1618. }
  1619.  
  1620.  
  1621. /*
  1622. =================
  1623. Controls_Cache
  1624. =================
  1625. */
  1626. void Controls_Cache( void ) {
  1627.     trap_R_RegisterShaderNoMip( ART_BACK0 );
  1628.     trap_R_RegisterShaderNoMip( ART_BACK1 );
  1629.     trap_R_RegisterShaderNoMip( ART_FRAMEL );
  1630.     trap_R_RegisterShaderNoMip( ART_FRAMER );
  1631. }
  1632.  
  1633.  
  1634. /*
  1635. =================
  1636. UI_ControlsMenu
  1637. =================
  1638. */
  1639. void UI_ControlsMenu( void ) {
  1640.     Controls_MenuInit();
  1641.     UI_PushMenu( &s_controls.menu );
  1642. }
  1643.